package com.itbaiyun.usercenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itbaiyun.usercenter.common.BaseResponse;
import com.itbaiyun.usercenter.common.ResultUtil;
import com.itbaiyun.usercenter.mapper.UserFollowMapper;
import com.itbaiyun.usercenter.model.domain.User;
import com.itbaiyun.usercenter.model.domain.UserFollow;
import com.itbaiyun.usercenter.service.UserFollowService;
import com.itbaiyun.usercenter.service.UserService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.itbaiyun.usercenter.constant.RedisConstant.FOLLOW_USER_KET;

/**
 * @author O
 * @description 针对表【user_follow(用户关注关系表)】的数据库操作Service实现
 * @createDate 2024-08-16 17:40:09
 */
@Service
public class UserFollowServiceImpl extends ServiceImpl<UserFollowMapper, UserFollow>
        implements UserFollowService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private UserService userService;


    /**
     * 关注用户功能实现
     *
     * @param followId 要关注的用户id
     * @param isFollow 是否已经关注
     * @return 返回结果
     */
    @Override
    public BaseResponse<Boolean> followUser(Long followId, boolean isFollow, HttpServletRequest request) {
        //根据id获得用户
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();

        //关注redis的key
        String key = FOLLOW_USER_KET + userId;
        //判断是否已经关注
        if (!isFollow) {
            //未关注则关注
            UserFollow userFollow = new UserFollow();
            userFollow.setFollowId(followId);
            userFollow.setUserId(userId);
            userFollow.setIsDelete(0);
            userFollow.setCreateTime(new Date());
            boolean save = this.save(userFollow);
            //关注成功之后写入数据库
            if (save) {
                stringRedisTemplate.opsForSet().add(key, followId.toString());
            }
            return ResultUtil.sucess(save);
        } else {
            //已关注则取消关注
            boolean remove = this.remove(new QueryWrapper<UserFollow>().eq("userId", userId).eq("followId", followId));
            //成功在数据库取消关注之后再把缓存中的内容删除
            if (remove) {
                stringRedisTemplate.opsForSet().remove(key, followId.toString());
            }
            return ResultUtil.sucess(remove);
        }

    }

    /**
     * 是否已经关注
     *
     * @param followId 被关注人id
     * @param request  获取登录用户
     * @return 返回结果
     */
    @Override
    public boolean isFollow(Long followId, HttpServletRequest request) {
        //根据id获得用户
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        //是否已经关注
        Long count = query().eq("userId", userId).eq("followId", followId).count();
        //count>0 表示已关注该用户
        return count > 0;
    }

    /**
     * 查询公共关注的好友
     *
     * @param followId 被关注人id
     * @param request  获取登录用户
     * @return 返回结果
     */
    @Override
    public List<User> findCommonUser(Long followId, HttpServletRequest request) {
        //获取登录用户
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        //当前登录用户的key
        String key1 = String.format(FOLLOW_USER_KET + userId);
        //关注人的key
        String key2 = String.format(FOLLOW_USER_KET + followId);
        //查找两个用户之间的共同关注
        Set<String> strIds = stringRedisTemplate.opsForSet().intersect(key1, key2);
        //如果没有关注他的人,则返回空集合
        if (strIds == null || strIds.isEmpty()){
            return Collections.emptyList();
        }
        //如果有关注他的人,ids解析-->string转为long
        List<Long> ids = strIds.stream().map(Long::valueOf).collect(Collectors.toList());
        //根据ids获取用户脱敏信息
        List<User> users = userService.listByIds(ids).stream().map(userService::getSafetyUser).collect(Collectors.toList());
        //返回
        return users;
    }

}




